package com.zang.blogz.service.impl;

import cn.dev33.satoken.exception.NotPermissionException;
import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zang.blogz.constant.AuthorConstant;
import com.zang.blogz.constant.CommentConstant;
import com.zang.blogz.constant.MessageConstant;
import com.zang.blogz.constant.ResultConstant;
import com.zang.blogz.entity.Comment;
import com.zang.blogz.entity.Message;
import com.zang.blogz.entity.UserInfo;
import com.zang.blogz.exception.BizException;
import com.zang.blogz.mapper.MessageMapper;
import com.zang.blogz.modle.output.MessageVO;
import com.zang.blogz.result.Result;
import com.zang.blogz.service.MessageService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zang.blogz.utils.BeanCopyUtils;
import com.zang.blogz.utils.IpUtil;
import com.zang.blogz.utils.LimitUtil;
import com.zang.blogz.utils.UserInfoUtil;
import io.github.vampireachao.stream.core.optional.Opp;
import io.github.vampireachao.stream.core.optional.Sf;
import io.github.vampireachao.stream.plugin.mybatisplus.Database;
import io.github.vampireachao.stream.plugin.mybatisplus.Many;
import io.github.vampireachao.stream.plugin.mybatisplus.One;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicReference;

import static com.zang.blogz.constant.MessageConstant.*;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 朵橙i
 * @since 2022-06-17
 */
@Service
public class MessageServiceImpl extends ServiceImpl<MessageMapper, Message> implements MessageService {

    @Value("${userinfo.default.avatar}")
    private String avartar;

    @Value("${userinfo.default.nickname}")
    private String nickname;

    @Autowired
    private LimitUtil limit;

    @Override
    public Message saveMessage(String message) {

        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = (HttpServletRequest) Objects.requireNonNull(requestAttributes).resolveReference(RequestAttributes.REFERENCE_REQUEST);

        String ipAddress = IpUtil.getIpAddress(request);
        String ipSource = IpUtil.getIpSource(ipAddress);

        if (!limit.canAccess(ipAddress, 60, 1)) {

            throw new BizException("每个用户每分钟只能留言一次");
        }
        Object loginId = StpUtil.getLoginIdDefaultNull();

        Opp.of(loginId).ifPresent(id -> {
            UserInfo query = One.of(UserInfo::getId).eq((Integer) id).query();
            avartar = query.getAvatar();
            nickname = query.getNickname();
        });

        Message info = new Message();

        info.setNickname(nickname);
        info.setAvatar(avartar);
        info.setMessageContent(message);
        info.setIpAddress(ipAddress);
        info.setIpSource(ipSource);
        info.setIsReview(MessageConstant.approvalFlag.get(CommentConstant.APPROVAL_STATUS));
        if (Database.save(info)){
            return info;
        }else {
            throw new BizException(ResultConstant.MESSAGE_FAIL);
        }
    }

    @Override
    public List<String> listMessage() {

       return Many.of(Message::getIsReview).eq(CommentConstant.TRUE)
               .value(Message::getMessageContent)
               .query();
    }

    @Override
    public IPage<MessageVO> adminListMessage(Page<Message> page) {

        IPage<Message> pageVo = Database.page(page, Message.class);

        return pageVo.convert(res -> {

            MessageVO vo = BeanCopyUtils.copyObject(res, MessageVO.class);
            vo.setIsReview(StringUtils.equals(res.getIsReview(), MessageConstant.TRUE));
            return vo;
        });
    }

    @Override
    public String approved(Integer messageId) {


        Database.update(Wrappers.lambdaUpdate(Message.class)
                .eq(Message::getId, messageId)
                .set(Message::getIsReview, MessageConstant.TRUE));

        return ResultConstant.STATE_SUCCESS;

    }

    @Override
    public String openMessageCheck() {

        MessageConstant.approvalFlag.put(APPROVAL_STATUS, TRUE);

        return ResultConstant.STATE_SUCCESS;
    }

    @Override
    public String downMessageCheck() {
        MessageConstant.approvalFlag.put(APPROVAL_STATUS, FALSE);

        return ResultConstant.STATE_SUCCESS;
    }

    private void isCan(){

        String name = (String) StpUtil.getExtra("name");

        boolean contains = AuthorConstant.authorSet.contains(name);

        if (!contains) {

            throw new NotPermissionException("你没有最高管理员权限不能更改此状态");
        }
    }
}
